﻿namespace OutLook.Module.Load
{
    using System;
    using System.Collections.Generic;
    using System.Data;
    using System.IO;
    using System.Linq;
    using OutLook.Model.Domains;
    using OutLook.Model.Infrastructure;
    using OutLook.Module.Infrastructure.Interfaces;
    using OutLook.Module.Load.Contracts;

    /// <summary>
    /// TODO: Update summary.
    /// </summary>
    public class LoadPackage : ILoadContract, IUserContract, ITechnologyContract, IModelContract, IOutputContract
    {
        #region Constructors

        private LoadPackage()
        {
            LoadStorage.Instance.Initialize<User>(Path.Combine(m_Resolver.ResolvePath(@"Data\Users"), "Users.xml"));
            m_UserController = new UserController(LoadStorage.Instance);
            m_LoadController = new LoadController(null);
            m_ModelController = new ModelController(null);
            m_OutputController = new OutputController(null);
            m_TechnologyController = new TechnologyController(null);
        }

        #endregion

        #region Properties

        /// <summary>
        /// Gets instance of service locator
        /// </summary>
        public static LoadPackage Instance
        {
            get
            {
                lock (__murex)
                {
                    if (m_LoadPackage == null)
                        m_LoadPackage = new LoadPackage();

                    return m_LoadPackage;
                }
            }
        }

        public Model CurrentModel
        {
            get
            {
                return m_ModelController.CurrentModel;
            }
            set
            {
                m_ModelController.CurrentModel = value;
            }
        }

        public Load CurrentLoad
        {
            get { return m_LoadController.CurrentLoad; }
            set { m_LoadController.CurrentLoad = value; }
        }

        public string CurrentLoadFileName
        {
            get { return m_LoadController.CurrentLoadFileName; }
        }

        public Technology CurrentTechnology
        {
            get
            {
                return m_TechnologyController.CurrentTechnology;
            }
            set
            {
                m_TechnologyController.CurrentTechnology = value;
            }
        }

        public Output CurrentOutput
        {
            get
            {
                return m_OutputController.CurrentOutput;
            }
            set
            {
                m_OutputController.CurrentOutput = value;
            }
        }

        #endregion

        #region ILoadContract Implementation

        public System.Data.DataTable DownloadTheLoad(string fileName)
        {
            return m_LoadController.DownloadTheLoad(fileName);
        }

        public System.Data.DataTable ChargeIndicators()
        {
            return m_LoadController.ChargeIndicators();
        }

        public List<string> GetAllChemicalСombinationsInAllCharges()
        {
            return m_LoadController.GetAllChemicalСombinationsInAllCharges();
        }

        public void SetWeightForZ()
        {
            m_LoadController.SetWeightForZ();
        }

        public System.Data.DataTable ChargeProperties()
        {
            return m_LoadController.ChargeProperties();
        }

        #endregion

        #region IUserContract Implementation

        public void Registrate(User user)
        {
            m_UserController.Registrate(user);
        }

        public bool LogIn(string login, string password)
        {
            return m_UserController.LogIn(login, password);
        }

        public void LogOut()
        {
            m_UserController.LogOut();
        }

        public bool ChangePassword(string currentPassword, string newPassword, string newPasswordConfirm)
        {
            return m_UserController.ChangePassword(currentPassword, newPassword, newPasswordConfirm);
        }

        public bool RecoverPassword(string email)
        {
            return m_UserController.RecoverPassword(email);
        }

        public User ViewProfile()
        {
            return m_UserController.ViewProfile();
        }

        public bool EditProfile(User user)
        {
            return m_UserController.EditProfile(user);
        }

        public User GetCurrentUser()
        {
            return m_UserController.GetCurrentUser();
        }

        #endregion

        #region ITechnologyContract Implementation

        public void CalcTehnologyParametrs()
        {
            m_TechnologyController.CalcTehnologyParametrs();
        }

        public System.Data.DataTable DownloadTheTechnology(string fileName)
        {
            string technFileName = Path.Combine(Path.GetDirectoryName(fileName), Path.GetFileNameWithoutExtension(fileName) + "Technology" + Path.GetExtension(fileName));

            if (File.Exists(technFileName))
                return m_TechnologyController.DownloadTheTechnology(technFileName);

            return null;
        }

        #endregion

        #region IModelContract Implementation

        public double GetElementDistribution(ElementModel rule, Load load, Technology technology)
        {
            return m_ModelController.GetElementDistribution(rule, load, technology);
        }

        public double GetElementDistribution(string rule, Load load, Technology technology)
        {
            throw new NotImplementedException();
        }

        #endregion

        #region IOutputContract Implementation

        public void SetOutput()
        {
            string elemDistrFileName = Path.Combine(Path.GetDirectoryName(m_LoadController.CurrentLoadFileName), "ElementsDistribution" + Path.GetExtension(m_LoadController.CurrentLoadFileName));
            string modelFileName = Path.Combine(Path.GetDirectoryName(m_LoadController.CurrentLoadFileName), "Model" + Path.GetExtension(m_LoadController.CurrentLoadFileName));
            ElementsDistribution distribution = DataSerializerHelper.XmlRead<ElementsDistribution>(elemDistrFileName);
            m_ModelController.CurrentModel = DataSerializerHelper.XmlRead<Model>(modelFileName);

            GetOutput(CurrentLoad, CurrentModel, distribution, CurrentTechnology);
        }

        public void GetOutput(Load load, Model model, ElementsDistribution distribution, Technology technology)
        {
            m_OutputController.GetOutput(load, model, distribution, technology);
        }

        public DataTable GetCastIron()
        {
            return m_OutputController.GetCastIron();
        }

        public DataTable GetSlag()
        {
            return m_OutputController.GetSlag();
        }

        public void CalcOutputProperties()
        {
            throw new NotImplementedException();
        }

        #endregion

        #region Fields

        private IUserContract m_UserController;
        private IPathResolver m_Resolver = new LocalPathResolver();
        private ILoadContract m_LoadController;
        private IModelContract m_ModelController;
        private IOutputContract m_OutputController;
        private ITechnologyContract m_TechnologyController;
        private readonly static object __murex = new object();
        private static LoadPackage m_LoadPackage = default(LoadPackage);

        private Output m_output;

        #endregion   
      
    }
}
